package org.wheel.plugins.toolkit.jdbc.pool.util.excution;

import lombok.Getter;
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.wheel.plugins.toolkit.sql.enums.SqlModel;
import org.wheel.plugins.toolkit.util.sql.SQLHelper;

import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Objects;

/**
 * SQL 模型解析器：把 MyBatis/NUMBER/PROPERTY_NAME/NATIVE 统一解析成
 * 最终可执行 SQL + 参数数组/Map
 */
public final class SqlModelResolver {

    private SqlModelResolver() {}

    /**
     * 解析结果封装
     */
    public static final class ResolvedSql {
        @Getter
        private final String finalSql;
        private final Object[] args;
        @Getter
        private final MapSqlParameterSource paramSource;

        private ResolvedSql(String finalSql, Object[] args, MapSqlParameterSource paramSource) {
            this.finalSql = finalSql;
            this.args = args;
            this.paramSource = paramSource;
        }

        public Object[] getArgs() {
            if (args == null && paramSource != null) {
                // 兼容 JdbcTemplate 数组参数：按顺序取 values
                return Objects.requireNonNull(paramSource.getValues()).values().toArray();
            }
            return args;
        }
    }

    /* ========================== 对外 API ========================== */

    /**
     * 统一入口
     */
    public static ResolvedSql resolve(String sql, LinkedHashMap<String, Object> param, SqlModel model) {
        if (model == null) {
            throw new IllegalArgumentException("SqlModel 不能为空");
        }
        switch (model) {
            case MYBATIS:
                return resolveMybatis(sql, param);
            case PROPERTY_NAME:
                return resolvePropertyName(sql, param);
            case NUMBER:
                return resolveNumber(sql, param);
            case DIRECT_SQL:
                return resolveDirect(sql);
            case NATIVE:
                return resolveNative(sql, param);
            default:
                throw new IllegalArgumentException("未知 SQL 模型: " + model);
        }
    }

    /* -------------------- 私有实现 -------------------- */

    private static ResolvedSql resolveMybatis(String sql, LinkedHashMap<String, Object> param) {
        String finalSql = SQLHelper.resolve(sql, param);   // 把 #{xxx} 换成 :xxx
        return resolvePropertyName(finalSql, param);
    }

    private static ResolvedSql resolvePropertyName(String sql, LinkedHashMap<String, Object> param) {
        MapSqlParameterSource source = new MapSqlParameterSource(param);
        return new ResolvedSql(sql, null, source);
    }

    private static ResolvedSql resolveNumber(String sql, LinkedHashMap<String, Object> param) {
        Map<String, Object> numberMap = SQLHelper.resolveNumberParameters(param);
        MapSqlParameterSource source = new MapSqlParameterSource(numberMap);
        return new ResolvedSql(sql, null, source);
    }

    private static ResolvedSql resolveDirect(String sql) {
        return new ResolvedSql(sql, null, null);
    }

    private static ResolvedSql resolveNative(String sql, LinkedHashMap<String, Object> param) {
        Object[] args = param == null ? new Object[0] : param.values().toArray();
        return new ResolvedSql(sql, args, null);
    }
}